#!/usr/bin/python3
# -*- coding:utf-8 -*-
""""
   @Author: lijk34925
   @Time: 2024/4/8 17:08
   @File: BasicCommonMethods.py
   @desc:
"""
import time

from qturboframe.lib.utils.variable import Variable
from qturboframe.lib.webdriver import SeleniumError

from BladeFerm.Lib.Common import DownPath, logger
from BladeFerm.hui12_common.check_data import check_file_exit
from BladeFerm.hui2_app.basic import FE
from BladeFerm.utils.basic_opration import delete_dir_file
from HGScripts.common_test_prepare import common_test_prepare, open_menu_nk

from CommonScripts.check_result_hui_two import check_table
from CommonScripts.common_method_hui_two import arm_form_fill, form_data_fill


@common_test_prepare
def common_query_method(input_data=None, ui_expect=None):
    """
    通用的页面查询和结果断言功能；匹配关键词：`下钻查询`
        若input中存在return关键字，则将获取页面目标化的关键列值，将其设置为全局变量。
        若存在click关键字，则进行点击下钻。若值未配置，会从期望中找，一般建议先配置期望检查，检查存在再进行下钻。
    :param input_data: {'菜单名称':'客户信息管理/个人户信息查询|客户信息管理/交易流水查询-交易申请',
                        'varg_flow_no': '实例编号',
                        '操作|C':'处理',
                        '客户名称':'张三',
                        '证件号码':'123456789012345678'}
    :param ui_expect:
    :return:
    """
    def __deal_input_data(raw_input_data):
        __return_columns = {}
        __click_column = {}
        __input_data = {}
        for k, v in raw_input_data.items():
            if k.startswith("varg_"):
                __return_columns[k] = v
            elif k.endswith("|C"):
                sk = k.split("|C")[0]
                __click_column[sk] = v
            else:
                __input_data[k] = v
        return __input_data, __return_columns, __click_column

    def __main_query_step(v_input_data, v_ui_expect):
        open_menu_flag = False
        # 步骤1（可选）：打开菜单
        menu_name = v_input_data.pop("入口", "信用业务-融资融券-查询统计-合约明细")
        if menu_name:
            open_menu_nk({'菜单名称': menu_name})
            open_menu_flag = True
        # 步骤2：表达输入，点击查询
        arm_form_fill(v_input_data)
        # 步骤3：查询结果断言
        tablePage = check_table(input_data=v_input_data, ui_expect=v_ui_expect)
        # 步骤4（可选）：获取查询结果，把某一行某一列的值返回。
        if return_columns and tablePage:
            BladeVariable = Variable()
            for map_key, map_value in return_columns.items():
                cols_value = tablePage.get_target_cell({map_value: ''})
                col_value = cols_value[0] if cols_value else ''
                BladeVariable.set_variable(map_key, col_value)
                logger.info(f"设置全局变量：{map_key} = {col_value}")
        # 步骤5（可选）：查询结果，点击下钻，查看细节
        if click_column:
            tablePage.click_filter_cell(click_column)
            time.sleep(1)
        return open_menu_flag
    # 主逻辑：通用查询
    input_data, return_columns, click_column = __deal_input_data(input_data)
    result_flag, retry_result, index = True, True, 0
    __main_query_step(input_data, ui_expect)
    if not retry_result:
        raise SeleniumError(f"查询重试失败，请检查错误日志！")


@common_test_prepare
def common_detail_query(input_data=None, ui_expect=None):
    """
    二级页面查询：打开一级页面后点击详情，待二级页面打开后查询。匹配关键词：`下钻查询`
    :param input_data:
    :param ui_expect:
    :return:
    """
    # 下钻打开页面详情
    click_params = {}
    for k, v in input_data.items():
        if k.startswith('下钻|'):
            input_data.pop(k)
            k2 = k.split('|')[-1]
            click_params[k2] = v
    table = FE.table_new()
    table.click_cell(input_data=click_params, click_input=click_params)
    time.sleep(1)
    # 二级页面查询
    arm_form_fill(input_data)
    # 结果断言
    check_table(input_data=input_data, ui_expect=ui_expect)


@common_test_prepare
def common_add_data(input_data=None, ui_expect=None):
    """
    新增功能（新增数据，必填项校验，重复增加数据的校验）。
    使用前前置条件应该删除此数据，避免重复新增，重复新增会报错（允许新增：否，这种场景不会报错）
    :param input_data:
        入口: 信用业务-融资融券-参数设置-客户维持担保比例参数设置
        操作：保存|取消|重置 -- 可选输入，默认保存
        允许保存：是|否
    :param ui_expect:
        为空不校验；不为空，校验必填项的错误提示信息，例如：营业部：请选择一个营业部
        允许保存： 是/否 -- 可选输入，默认是（当重复添加时，判断不允许时填写 否，其他条件默认是）
    :return:
    """
    # 步骤1（可选）：打开菜单
    menu_name = input_data.pop("入口", "信用业务-融资融券-参数设置-客户维持担保比例参数设置")
    page_button = input_data.pop("btn_name", "新增")
    if menu_name:
        open_menu_nk({'菜单名称': menu_name})
    FE.button(page_button).click()
    # 步骤2：表单输入后断言必填项
    form_data_fill(input_data, ui_expect)


@common_test_prepare
def common_modify_data(input_data=None, ui_expect=None):
    """
    修改功能
    :param input_data:
        入口: 信用业务-融资融券-参数设置-客户维持担保比例参数设置
        勾选条件：客户号=12191
        更新信息：备注=test123
        操作：保存|取消|重置
        允许保存：是|否
    :param ui_expect:
    :return:
    """
    def __parse_params(key, val):
        if not val:
            error = f"请配置{key}！格式：【{key}：A=1;B=2】"
            logger.error(error)
            raise SeleniumError(error)
        row_dict = dict()
        for unit in val.split(';'):
            k, v = unit.split('=')
            row_dict.update({k: v})
        return row_dict
    # 步骤1（可选）：打开菜单
    menu_name = input_data.pop("入口", "信用业务-融资融券-参数设置-客户维持担保比例参数设置")
    select_row = input_data.get("勾选条件", '')
    modify_row = input_data.get("更新信息", '')
    if menu_name:
        open_menu_nk({'菜单名称': menu_name})
    # 步骤2：勾选目标行
    select_row_dict = __parse_params("勾选条件", select_row)
    table_element = FE.table_new()
    table_element.select_row(header_content=select_row_dict)
    # 步骤3：点击修改按钮，然后修改
    FE.button("修改").click()
    modify_row_dict = __parse_params("更新信息", modify_row)
    form_data_fill(modify_row_dict, ui_expect)


@common_test_prepare
def common_delete_data(input_data=None, ui_expect=None):
    """
    删除功能
    :param input_data:
        入口: 信用业务-融资融券-查询统计-合约明细
        操作：确定|取消
        others
    :param ui_expect:
    :return:
    """
    # 步骤1（可选）：打开菜单
    menu_name = input_data.pop("入口", "信用业务-融资融券-查询统计-合约明细")
    btn_name = input_data.pop("操作", "确定")
    if menu_name:
        open_menu_nk({'菜单名称': menu_name})
    if btn_name == "未选中":
        pass
    else:
        # 步骤2：先查询筛选出来后再勾选
        arm_form_fill(input_data)
        table_element = FE.table_new()
        table_element.select_row(header_content=input_data)
    # 步骤3：点击修改按钮，然后修改
    FE.button("删除").click()
    if btn_name == '未选中':
        msg_confirm = FE.msg_box('请选择数据进行删除', timeout=3)
        if not msg_confirm.exist():
            raise SeleniumError("未选中数据时无弹出提示框！")
    # 步骤4：确认删除
    msg_confirm = FE.msg_box('删除', timeout=3)
    msg_confirm.click_button(btn_name, idname={'xpath': './/div[@class="h-modal-confirm-footer"]/button/span'})


@common_test_prepare
def common_export_data(input_data=None, ui_expect=None):
    """
    导出功能
    :param input_data:
        入口: xxxx-xxx-xx
        导出类型: 导出全部行/导出选中行
        others: 导入选中行 的筛选条件
    :param ui_expect:
    :return:
    """
    menu_name = input_data.pop("入口", None)
    button_name = input_data.pop("导出类型", "导出全部行")
    filename = input_data.pop("文件名", None)
    if menu_name:
        filename = menu_name.split('-')[-1]
        # 步骤2（可选）：打开菜单
        open_menu_nk({'菜单名称': menu_name})
        # 步骤3：表达输入，点击查询
        if len(input_data.keys()) > 0:
            arm_form_fill(input_data)
    if filename:
        # 步骤1：清理历史数据
        delete_dir_file(filename, DownPath)
    # 步骤4：导出数据
    table_element = FE.table_new()
    table_element.export_row(filter=input_data, button_name=button_name)
    msg_confirm = FE.msg_box(timeout=3)
    msg_confirm.click_button("关闭")
    # 步骤5：检查导出结果
    if filename:
        check_file_exit(filename)


# 装饰器必填：实现登录检查，数据预埋，异常捕获等功能
@common_test_prepare
def test_demo(input_data=None, ui_expect=None):
    # 步骤1：打开菜单
    open_menu_nk({'菜单名称': '信用业务-融资融券-查询统计-合约明细'})
    # 步骤2：业务操作步骤
    pass
    # 步骤3：获取结果进行断言
    pass